package com.hashbee.filter;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import com.hashbee.ctxinit.Audience;
import com.hashbee.user.model.UserVo;
import com.hashbee.util.JwtUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.DatatypeConverter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;


public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);  
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String header = request.getHeader("Authorization");
        if("OPTIONS".equals(request.getMethod())) {
        	response.setStatus(response.SC_OK);
        	chain.doFilter(request, response);
        }else {
            if (header == null || !header.startsWith(JwtUtils.getAuthorizationHeaderPrefix())) {
                chain.doFilter(request, response);
                return;
            }
            
            UsernamePasswordAuthenticationToken authenticationToken = getUsernamePasswordAuthenticationToken(header);

            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            chain.doFilter(request, response);
        }
    }

    private UsernamePasswordAuthenticationToken getUsernamePasswordAuthenticationToken(String token) {
		try {
	    	Claims claims = Jwts.parser()
	                .setSigningKey(DatatypeConverter.parseBase64Binary(new Audience().getBase64Secret()))
	                .parseClaimsJws(token.replace(JwtUtils.getAuthorizationHeaderPrefix(), "")).getBody();
	
	    	Map mapper = (Map) claims.get("user");
	    	UserVo user = null;

			user = (UserVo) JwtUtils.convertMap(UserVo.class, mapper);
//			user.setId(Integer.parseInt(mapper.get("id")+""));
	        if (null != user) 
	            return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
    }
    
}
